#include <iostream>
#include <string>
#include <vector>
#include <list>
#include <set>
#include <algorithm>
#include <functional>
using namespace std;

template <typename T>
class IsDiv
{
public:
	IsDiv(const T &divsor)
	{
		this->divsor = divsor;
	}
	//接受一个参数的函数，叫做一元函数，如果一元函数返回布尔值，则该函数成为一元谓词；接受两个参数的函数为二元函数，如果返回一个布尔值，则该函数称为二元谓词。
	bool operator()(T &t)
	{
		return (t%divsor == 0);
	}
private:
	T divsor;
};
//一元谓词的使用
void wei_ci()
{
	vector<int> v;
	for (int i = 0; i < 10; i++)
	{
		v.push_back(i);
	}
	int a = 4;
	IsDiv<int> myDiv(a);
	//查找能被a整除的元素
	vector<int>::iterator  it = find_if(v.begin(), v.end(), myDiv);
	while (it != v.end())
	{
		cout << "被4整除的元素是:" << *it << endl;
		it++;
		it = find_if(it, v.end(), myDiv);

	}
}
//二元函数对象
template <typename T>
class SumAdd
{
public:
	T operator()(T &t1, T &t2)
	{
		return t1 + t2;
	}
};
void er_yuan_wei_ci()
{
	vector<int> v1, v2, v3;
	v1.push_back(1);
	v1.push_back(2);
	v1.push_back(3);

	v2.push_back(4);
	v2.push_back(5);
	v2.push_back(6);

	v3.resize(10);//调整容器的长度大小，使其能容纳n个元素。如果n小于容器的当前的size，则删除多出来的元素。否则，添加采用值初始化的元素。
	/*
    OutputIterator transform ( InputIterator1 first1,     // 源容器1的起始地址
    InputIterator1 last1,       // 源容器1的终止地址
    InputIterator2 first2,      // 源容器2的起始地址，元素个数与1相同
    OutputIterator result,      // 目标容器的起始地址，元素个数与1相同
    BinaryOperator binary_op ); // 函数指针
    */
	//两个容器中对应位置的元素求和插入到第三个容器中，返回第三个容器插入最后一个元素的后一个元素迭代器
	vector<int>::iterator it = transform(v1.begin(), v1.end(), v2.begin(), v3.begin(), SumAdd<int>());

	for (it--; it != v3.begin() - 1; it--)
	{
		cout << *it << "\t" << endl; //9 7 5
	}
}
/*
预定义的函数对象:
加法：plus<Types>
减法：minus<Types>
乘法：multiplies<Types>
除法divides<Tpye>
求余：modulus<Tpye>
取反：negate<Type>

等于equal_to<Tpye>
不等于not_equal_to<Type>
大于 greater<Type>
大于等于greater_equal<Type>
小于 less<Type>
小于等于less_equal<Type>
*/

//用于比较的谓词
template <typename T>
class MyCompare
{
public:
	bool operator()(const T &t1, const T &t2)
	{
		return  t1 < t2;
	}
};
//用于遍历的函数
template <typename T>
void print_ele(T &t)
{
	cout << t << "\t";
}

void compare_weici()
{
	vector<int> v1;
	v1.push_back(1);
	v1.push_back(9);
	v1.push_back(3);
	v1.push_back(8);
	v1.push_back(5);
	v1.push_back(7);
	//排序
	sort(v1.begin(), v1.end(), MyCompare<int>());
	//遍历
	for_each(v1.begin(), v1.end(), print_ele<int>);

}
//自定义set的排序
//仿函数
struct CompareNoCase
{
	//不区分大小写
	bool  operator()(const string &str1, const string &str2)const  //加const修饰，不能修改成员变量
	{

		string str1_;
		string str2_;
		str1_.resize(str1.size());
		str2_.resize(str2.size());
		//转小写
		transform(str1.begin(), str1.end(), str1_.begin(), tolower);
		transform(str2.begin(), str2.end(), str2_.begin(), tolower);
		return str1_ < str2_;//从小到大排列
	}
};

void my_set()
{
	set<string, CompareNoCase> s;
	s.insert("AAA");
	s.insert("bbb");
	s.insert("ddd");
	s.insert("GGG");
	s.insert("ccc");
	s.insert("EEE");

	for (set<string, CompareNoCase>::iterator it = s.begin(); it != s.end(); it++)
	{
		cout << *it << "\t";
	}
	cout << endl;
	//查找，不区分大小写
	set<string, CompareNoCase>::iterator it = s.find("aaa");
	cout << *it << endl;
}
int main2()
{
	//wei_ci();
	//er_yuan_wei_ci();
	//compare_weici();
	my_set();
	return 0;
}